/*
 *Copyright (c) [2019-2020]  C2comm, Inc.  All rights reserved.
 *
 *This program is free software; you can redistribute it and/or
 *modify it under the terms of the GNU General Public License
 *as published by the Free Software Foundation; either version 2
 *of the License, or (at your option) any later version.
 *
 *This program is distributed in the hope that it will be useful,
 *but WITHOUT ANY WARRANTY; without even the implied warranty of
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *GNU General Public License for more details.
 *
 *You should have received a copy of the GNU General Public License
 *along with this program; If not, see <https://www.gnu.org/licenses/>
 */

/*
 *Vendor: C2comm
 *Version: 1.0
 *Filename: LocalClockCtrl.v
 *Target Device: Altera
 *Author : 刘晓骏
*/


module LocalClockCtrl(
    input  wire         SYS2CORE_clk,
    input  wire         SYS2CORE_rst_n,
    
    output reg  [ 19:0] G_local_clk,
    
    input  wire [336:0] CONF2CORE_cm_static_conf,
    input  wire [ 42:0] G_current_state,

    input  wire         G_pcf_des_wr,
    input  wire [ 90:0] G_pcf_des,
    
    input  wire [ 19:0] SCP2LCC_clock_corr,//modify by lxj 20200427
    
    output wire [298:0] CORE2MON_cm_state,
    
    output reg          LCC2LICC_plus_1,
    input  wire         state_clr_trigger//状态机中的清零条件
    //针对local_clk/local_integrate_cycle/local_sync/async_membership
);
/*//////////////////////////////////////////////////////////
                    中间变量声明区域
*///////////////////////////////////////////////////////////
//本模块中所有中间变量(wire/reg/parameter)在此集中声明 
reg  [19:0] next_local_clk;

wire        clock_corr_trigger;

localparam CM_INTEGRATE  = 6'b000001,
           CM_UNSYNC     = 6'b000010,
           CM_CA_ENABLED = 6'b000100,
           CM_WAIT_4_IN  = 6'b001000,
           CM_SYNC       = 6'b010000,
           CM_STABLE     = 6'b100000;
//***************************************************
//              状态统计信号
//***************************************************          
assign CORE2MON_cm_state = {6'b0,
                            G_local_clk,
                            273'b0};
/*//////////////////////////////////////////////////////////
                      其他信号处理
*///////////////////////////////////////////////////////////
assign clock_corr_trigger = ((G_current_state[42:37] == CM_SYNC) && (G_current_state[2+8+6] == 1'b1)) || 
                            ((G_current_state[42:37] == CM_STABLE) && (G_current_state[2+0+5] == 1'b1));

always @* begin
    if((state_clr_trigger == 1'b1) ||
       ((G_local_clk + 1'b1)==CONF2CORE_cm_static_conf[248:229]))begin
        next_local_clk = 20'b0;
    end
    else if((G_pcf_des_wr == 1'b1) && (G_pcf_des[40:38] > 3'b0)) begin

        next_local_clk = CONF2CORE_cm_static_conf[79:60];
    end
    else if(clock_corr_trigger == 1'b1) begin
        next_local_clk = G_local_clk + SCP2LCC_clock_corr + 1'b1;
        
    end
    else begin
        next_local_clk = G_local_clk + 1'b1;
    end
end

always @(posedge SYS2CORE_clk or negedge SYS2CORE_rst_n) begin
    if(~SYS2CORE_rst_n) begin
        G_local_clk <= 20'b0;
    end
    else begin
        G_local_clk <= next_local_clk;
    end
end

//集成周期加1信号
always @(posedge SYS2CORE_clk or negedge SYS2CORE_rst_n) begin
    if(~SYS2CORE_rst_n) begin
        LCC2LICC_plus_1 <= 1'b0;
    end
    else begin
        LCC2LICC_plus_1 <= ((G_local_clk + 1'b1)==CONF2CORE_cm_static_conf[248:229]);
    end
end

/*//////////////////////////////////////////////////////////
                   IP调用区域
*///////////////////////////////////////////////////////////
//本模块调用的所有IP在该区域实例化
//例如fifo/ram/grant之类的IP.... 
endmodule
/*
LocalClockCtrl LocalClockCtrl_inst(
    .SYS2CORE_clk(),
    .SYS2CORE_rst_n(),

    .G_local_clk(),

    .CONF2CORE_cm_static_conf(),
    .G_current_state(),

    .G_pcf_des_wr(),
    .G_pcf_des(),

    .SCP2LCC_clock_corr(),

    .CORE2MON_cm_state(),

    .LCC2LICC_plus_1(),
    .state_clr_trigger()//状态机中的清零条件
    //针对local_clk/local_integrate_cycle/local_sync/async_membership
);
*/